package com.muse;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @description 参数化类型
 * @author: muse
 **/
public class ParameterizedTypeDemo {
    public static void main(String[] args) {
        /**
         * 测试一：具有<>符号的变量是参数化类型
         */
        System.out.println("--------------------- instanceof ParameterizedType ---------------------");
        Field[] fields = ParameterizedBean.class.getDeclaredFields();
        Arrays.stream(fields).forEach(field -> {
            System.out.println(field.getName() + ":" + (field.getGenericType() instanceof ParameterizedType));
        });

        /**
         * 测试二：getActualTypeArguments()返回了一个Type数组，数组里是参数化类型的参数
         */
        System.out.println("--------------------- getActualTypeArguments() ---------------------");
        Arrays.stream(fields).filter(field -> field.getGenericType() instanceof ParameterizedType).forEach(field -> {
            ParameterizedType pType = (ParameterizedType) field.getGenericType();
            System.out.print("变量: "+ pType.getTypeName()+"     ");
            Type[] types = pType.getActualTypeArguments();
            Arrays.stream(types).forEach(type -> System.out.print("类型: "+type.getTypeName() + " "));
            System.out.println();
        });

        /**
         * 测试三：getRawType()获取变量的类型
         */
        System.out.println("--------------------- getRawType() ---------------------");
        Arrays.stream(fields).filter(field -> field.getGenericType() instanceof ParameterizedType).forEach(field -> {
            ParameterizedType pType = (ParameterizedType) field.getGenericType();
            System.out.print("变量: "+ pType.getTypeName() + "     " + "RawType: " + pType.getRawType().getTypeName());
            System.out.println();
        });

        StringBuffer.class.getGenericInterfaces();
    }
}

class ParameterizedBean {
    public List<String> list1;
    public List list2;
    public Map<String,Long> map1;
    public Map map2;
    public Map.Entry<Long,Short> map3;
}